const rewire = require('rewire')
const axios = rewire('axios')
const R = require('ramda')
const moment = require('moment')
const {httpGet, httpPost} = rewire('../common/utils.cjs')
const config = rewire('../config.cjs')
const dto = rewire('../common/dto.cjs')
const tools = rewire('../common/tools.cjs')
const combinator = rewire('../common/combinator.cjs')
const db = rewire('../common/dbutils.cjs')
const state = rewire('../state.cjs')


async function apiTest() {
  const resp = await httpPost('https://udid.nmpa.gov.cn/api/v2/connection/test')
  console.log(resp.data)
}

async function requestApi(url, params) {
  const resp = await axios({
    method: 'post',
    url,
    data: {
      "params": JSON.stringify(params)
    },
    transformRequest: [
      function (data) {
        let ret = ''
        for (let it in data) {
          ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
        }
        ret = ret.substring(0, ret.lastIndexOf('&'));
        return ret
      }
    ],
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    }
  })
  return resp.data
}

async function apiToken() {
  const resp = await requestApi('https://udid.nmpa.gov.cn/api/v2/token/get', {
    "appId": config.UdiAppId,
    "appSecret": config.UdiSecret,
    "TYSHXYDM": config.TYSHXYDM
  })

  if (R.isEmpty(resp) || resp.returnCode != 1 || R.isEmpty(resp.accessToken)) {
    throw new Error('请求apiToken接口错误：' + JSON.stringify(resp))
  }

  console.log(resp)
  return resp
}



async function apiShareGet(date, page) {
  const getApiToken = tools.wrapCacheFn(apiToken, 'UdiToken', 3600 * 12)
  const tokenObj = await getApiToken()

  const resp = await requestApi('https://udid.nmpa.gov.cn/api/v2/sharing/get', {
    "accessToken": tokenObj.accessToken,
    "requestType": 1,
    "rangeValue": date,
    "currentPageNumber": page
  })

  if (R.isEmpty(resp) || resp.returnCode != 1) {
    throw new Error('请求apiShareGet接口错误：' + JSON.stringify(resp))
  }
  console.log(resp)
  return resp
}




async function apiShareGetAll(date) {
  let page = 1
  const result = await combinator.mapUntil(R.partial(apiShareGet, [date]), 1, function(data) {
    return data.currentPageNumber == data.totalPageCount
  })

  const packingInfo = [].concat(...(R.map(function(item) {
    return item['dataSet']['packingInfo']
  }, result)))

  const storageInfo = [].concat(...(R.map(function(item) {
    return item['dataSet']['storageInfo']
  }, result)))

  const deviceInfo = [].concat(...(R.map(function(item) {
    return item['dataSet']['deviceInfo']
  }, result)))

  const clinicalInfo = [].concat(...(R.map(function(item) {
    return item['dataSet']['clinicalInfo']
  }, result)))

  return {packingInfo, storageInfo, deviceInfo, clinicalInfo}
}


let ddd = null
(async function() {
  ddd = await apiShareGetAll('2022-01-11')
})()

//apiShareGet('2022-01-11', 1)


async function apiShareSave(params) {
  // TODO
}


function isToday(date) {
  return date === moment().format('YYYY-MM-DD')
}

function isExpired(data, date) {
  // 总感觉不会过期
  return false
}


async function findDbList(date, page, size) {
  const prisma = state.getPrisma()
  const result = await prisma.device_record.findMany({
    where: {versionTime: {startsWith: date}},
    orderBy: {deviceRecordKey: 'desc'},
    skip: page * size,
    take: size
  })
  return result
}

async function updateDb(data) {
  const prisma = state.getPrisma()
  const {packingInfo, storageInfo, deviceInfo, clinicalInfo} = data
  await combinator.parallelMap(10, R.partial(db.saveOrUpdate, [prisma.device_record, 'deviceRecordKey']), deviceInfo)
  await combinator.parallelMap(10, R.partial(db.saveOrUpdate, [prisma.packing_info, 'deviceRecordKey']), packingInfo)
  await combinator.parallelMap(10, R.partial(db.saveOrUpdate, [prisma.storage_info, 'deviceRecordKey']), storageInfo)
  await combinator.parallelMap(10, R.partial(db.saveOrUpdate, [prisma.clinical_info, 'deviceRecordKey']), clinicalInfo)
}

async function findDbDetail(id) {
  const prisma = state.getPrisma()
  const info = await prisma.device_record.findUnique({
    where: {deviceRecordKey: id}
  })
  return info
}

function checkParams(params) {
  // TODO
}


async function notifyMessage(msg) {
  // TODO
}


async function list(date, page, size = 20) {
  // 如果是当天则不处理
  if (isToday(date)) {
    return dto.success([])
  }

  let data = await findDbList(date, page, size)
  // 如果查不到或者已过期，则调用接口
  if (R.isEmpty(data) || isExpired(data, date)) {
    const getFn = tools.wrapCacheFn(apiShareGetAll, 'UdiApiShareGet', 3600 * 12)
    const thirdDataRs = await getFn(token, date)
    if (thirdDataRs.success) {
      await updateDb(thirdDataRs.data)
      data = await findDbList(date, page, size)
    }
    else {
      return dto.fail(thirdDataRs.msg)
    }
  }
  return dto.success(data)
}

async function detail(id) {
  let data = await findDbDetail(id)
  if (data.success) {
    return dto.success(data)
  }

  return dto.fail(rs.msg)
}

async function save(params) {
  const valid = checkParams(params)
  if (!valid) {
    return fail(capi.paramsError, '参数错误')
  }
  const rs = await apiShareSave(params)
  if (rs.success) {
    if (rs.leftTimes <= 0) {
      await notifyMessage('上报接口次数已用完')
    }
    return dto.success()
  }
  else {
    return dto.fail(rs.msg)
  }
}

//apiShareGet('F9EF8852788C9F5C24FAE20D77E00777E59AE3EE9AEF8339C3ECE2D4D89D16E5D37890E5576973882031414DD19ABFC872C0F80BF1C8BD3805D0D117F3EB16DAD5FA1CE2B0F7D709CFA9E2416F4B1A1C094F18555163FF6D68A99081922338A9CCA3C8FB699F82FB')
